const Koa = require('koa');
const hbs = require('koa-hbs');
const json = require('koa-json');
const cors = require('koa2-cors');
const views = require('koa-views');
const koabody = require('koa-body');
const static = require('koa-static');
const logger = require('koa-logger');
const onerror = require('koa-onerror');
const session = require('koa-session2');
const iplocate = require('node-iplocate');
const swaggerUI = require('koa2-swagger-ui');
const hbsHeper = require('./libs/RegisterHbsHelper');

const app = new Koa();

// 跨域处理中间件。
app.use(cors({
  origin: '*',
  exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'],
  maxAge: 300,
  credentials: true,
  allowMethods: ['GET', 'POST', 'PUT', 'DELETE'],
  allowHeaders: ['Content-Type', 'Authorization', 'Accept'],
}));

// http请求体处理中间件。
app.use(koabody({
  multipart: true,
  formLimit: '20mb',
  jsonLimit: '50mb',
  textLimit: '50mb',
  enableTypes: ['json', 'form', 'text']
}));

// 集成swagger中间件。
app.use(swaggerUI({
  routePrefix: '/docs',
  swaggerOptions: {
    url: '/swagger.json'
  },
}));

// http请求json化。
app.use(json());

app.use(session({
  key: 'NJ_SESSIONID',
  maxAge: 1800000
}));

// app.use(logger());

// 静态文件处理中间件
app.use(static(__dirname + '/static'));
app.use(static(__dirname + '/uploads'));
app.use(static(__dirname + '/swagger'));

// 注册hbs帮助器。
hbsHeper.register();

// 基于hbs的视图引擎。
app.use(hbs.middleware({
  viewPath: `${__dirname}/views`,
  layoutsPath: `${__dirname}/views/layouts`,
  defaultLayout: 'default'
}));

const needLogons = ['/save', '/publish', '/LogisticsCenters'];

// 自定义拦截。
app.use(async (ctx, next) => {
  let isContinue = true;
  const start = new Date();

  if (ctx.request.path.startsWith('/api/')) {
    ctx.response.type = 'json';

    if (needLogons.find(c => ctx.request.path.endsWith(c))) {
      let user = ctx.session.user;

      if (!user) {
        isContinue = false;
      }
    }

    if (ctx.request.body.NeedLogOn) {
      let user = ctx.session.user;

      if (!user) {
        isContinue = false;
      } else {
        ctx.request.body.TenantGuid = user.TenantGUID;
      }
    }
  }

  if (isContinue) {
    // ip地址解析
    await iplocate(ctx.request.ip).then(rs => {
      ctx.iplocate = rs;
    });

    await next()
  } else {
    await (ctx.body = {
      at: new Date(),
      success: false,
      state: 401
    });
  }

  const ms = new Date() - start;

  // 在Http响应头中记录响应时间。
  ctx.set('X-Response-Time', `${ms}ms`);
});

// 注册koa2页面路由。
require('./routes/index')(app);

// 注册koa2 api路由
require('./apis/UserController')(app);
require('./apis/WarehouseController')(app);
require('./apis/RequirementController')(app);
require('./apis/NewsController')(app);
require('./apis/FileController')(app);
require('./apis/AllianceParaController')(app);
require('./apis/TenantController')(app);

// koa2错误处理
app.use(async (ctx, next) => {
  if (ctx.response.statusCode >= 400) {
    await ctx.render('error', {
      err: ctx.message
    });
  } else {
    await next();
  }
});

// 设置端口号。
app.port = parseInt(process.env.PORT || '6001');

// koa2服务器启动。
app.listen(app.port, () => {
  console.log(`http://127.0.0.1:${app.port} 已经启动(时间：${new Date().toLocaleString()})...`);
});